package MainBoard;

import Menu.ChooseLevel;
import Menu.InitialMenu;
import Model.Chess;
import Model.ChessCoord;
import Model.VictoryJudgement;
import Dialog.ChooseRoleDialog;
import Dialog.EndingDialog;
import Computer.*;

import java.awt.event.MouseEvent;
import java.io.*;

public class PVEChessBoard extends ChessBoard {
    //    游戏主界面
    private final PVEMainBoard mainBoard;
    //    用户选择的棋色
    private int role;
    private int computerRole;
    //    设置游戏状态
    private int result;
    private Computer computer = new Computer();

    /**
     * 棋室对战棋盘的构造函数
     *
     * @param mainBoard 棋室对战主界面
     */
    public PVEChessBoard(PVEMainBoard mainBoard) {
        this.mainBoard = mainBoard;
        this.initStep();
        this.endingDialog = new EndingDialog(mainBoard, "游戏结束", true);
    }

    /**
     * 设置用户执棋的颜色
     *
     * <p>会通过弹出对话框来使用户选择执棋颜色
     * 该方法将在MainBoard中被调用</p>
     */
    public void setRole() {
        ChooseRoleDialog chooseRoleDialog = new ChooseRoleDialog(mainBoard, "执棋选择", true);
        chooseRoleDialog.setVisible(true);
        this.role = chooseRoleDialog.getMessage();
        if (this.role == 2) {
            this.chessCoord[9][9] = Chess.black;
        }
        this.computerRole = this.role ^ 3;
    }

    /**
     * 设置游戏当前状态
     *
     * @param result 游戏状态，1表示正在游戏，0表示游戏结束
     */
    public void setResult(int result) {
        this.result = result;
    }

    /**
     * 游戏结束事件判定并更新rank记录
     *
     * @param winner 游戏的获胜者
     */
    public void overEvent(int winner) throws IOException {
        if (winner == role) {
            initChessBoard();
            if (mainBoard.getLevel() == ChooseLevel.primaryField) {
                File file = new File("src/records/primaryrecord.txt");
                ModifyRank(file, winner);
            } else if (mainBoard.getLevel() == ChooseLevel.mediumField) {
                File file = new File("src/records/mediumrecord.txt");
                ModifyRank(file, winner);
            } else if (mainBoard.getLevel() == ChooseLevel.seniorField) {
                File file = new File("src/records/seniorrecord.txt");
                ModifyRank(file, winner);
            }
            endingDialog.setWinnerInfo("恭喜获得胜利！");
            endingDialog.setVisible(true);
            setClickable(PVEMainBoard.CAN_NOT_CLICK);

            if (endingDialog.getMessage() == EndingDialog.back) {
                mainBoard.dispose();
                new InitialMenu();
            } else {
                this.initChessCoord();
            }
        } else if (winner == computerRole) {
            initChessBoard();
            if (mainBoard.getLevel() == ChooseLevel.primaryField) {
                File file = new File("src/records/primaryrecord.txt");
                ModifyRank(file, winner);
            } else if (mainBoard.getLevel() == ChooseLevel.mediumField) {
                File file = new File("src/records/mediumrecord.txt");
                ModifyRank(file, winner);
            } else if (mainBoard.getLevel() == ChooseLevel.seniorField) {
                File file = new File("src/records/seniorrecord.txt");
                ModifyRank(file, winner);
            }
            endingDialog.setWinnerInfo("很抱歉您失败了。");
            endingDialog.setVisible(true);
            setClickable(PVEMainBoard.CAN_NOT_CLICK);

            if (endingDialog.getMessage() == EndingDialog.back) {
                mainBoard.dispose();
                new InitialMenu();
            } else {
                this.initChessCoord();
            }
        }
    }

    /**
     * 修改排行榜记录文档
     *
     * @param file   修改的目标文件
     * @param winner 游戏的获胜者
     */
    private void ModifyRank(File file, int winner) throws IOException {
        String time = null;        // 速通纪录
        String winStreak = null;   // 连胜纪录
        String winNow = null;      // 当前连胜场次
        String winAll = null;      // 总胜利场次
        String timeAll = null;     // 总场次
        String winRate = null;     // 胜率
        if (file.length() == 0) {   // 文件初始化
            if (winner == role) {
                time = Long.toString(mainBoard.timeThread.millisecond);
                winStreak = "1";
                winNow = "1";
                winAll = "1";
                timeAll = "1";
                winRate = "1";
            } else if (winner == computerRole) {
                time = "尚未通关";
                winStreak = "0";
                winNow = "0";
                winAll = "0";
                timeAll = "1";
                winRate = "0";
            }
        } else {
            FileReader fileReader = new FileReader(file);
            BufferedReader bufferedReader = new BufferedReader(fileReader);
            time = bufferedReader.readLine();
            winStreak = bufferedReader.readLine();
            winNow = bufferedReader.readLine();
            winAll = bufferedReader.readLine();
            timeAll = bufferedReader.readLine();
            winRate = bufferedReader.readLine();
            bufferedReader.close();
            fileReader.close();
            if (winner == role) {
                if (time.equals("尚未通关"))
                    time = Long.toString(mainBoard.timeThread.millisecond);
                else if (mainBoard.timeThread.millisecond < Long.parseLong(time))
                    time = Long.toString(mainBoard.timeThread.millisecond);
                winNow = Integer.toString(Integer.parseInt(winNow) + 1);
                if (Integer.parseInt(winNow) > Integer.parseInt(winStreak))
                    winStreak = winNow;
                winAll = Integer.toString(Integer.parseInt(winAll) + 1);
            } else if (winner == computerRole)
                winNow = "0";
            timeAll = Integer.toString(Integer.parseInt(timeAll) + 1);
            winRate = Double.toString(Double.parseDouble(winAll) / Double.parseDouble(timeAll));
        }
        FileWriter fileWriter = new FileWriter(file);
        BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
        bufferedWriter.flush();
        bufferedWriter.write(time + "\r\n");
        bufferedWriter.write(winStreak + "\r\n");
        bufferedWriter.write(winNow + "\r\n");
        bufferedWriter.write(winAll + "\r\n");
        bufferedWriter.write(timeAll + "\r\n");
        bufferedWriter.write(winRate + "\r\n");
        bufferedWriter.close();
        fileWriter.close();
    }

    /**
     * 游戏结束后重新初始化棋盘
     */
    private void initChessBoard() {
        result = GAME_OVER;
        try {
            mainBoard.getTimeThread().interrupt();
        } catch (Exception e) {
            e.printStackTrace();
        }
        initChessCoord();
        initStep();
        mainBoard.buttonStart.setText("开始游戏");
        mainBoard.buttonStart.setEnabled(true);
    }

    /**
     * 设置下棋的点击事件
     *
     * @param e 鼠标点击事件
     */
    @Override
    public void mousePressed(MouseEvent e) {
        int winner;
        if (clickable) {
            chessX = e.getX();
            chessY = e.getY();
            if (chessX >= 30 && chessX <= 570 && chessY >= 30 && chessY <= 570) {
                int x = (chessX - 20) / 30;
                int y = (chessY - 20) / 30;

                if (chessCoord[x][y] == Chess.noChess) {
                    chessCoord[x][y] = role;
                    saveStep(x, y);
                    setClickable(PVEMainBoard.CAN_NOT_CLICK);
                    winner = VictoryJudgement.PPJudge(x, y, chessCoord, role);
                    try {
                        overEvent(winner);
                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                    }
                    if (result != GAME_OVER) {
                        ChessCoord computerCoord = computer.computePos(computerRole, chessCoord, mainBoard.getLevel());
                        chessCoord[computerCoord.getX()][computerCoord.getY()] = computerRole;
                        saveStep(computerCoord.getX(), computerCoord.getY());
                        winner = VictoryJudgement.PPJudge(computerCoord.getX(), computerCoord.getY(), chessCoord, computerRole);
                        try {
                            overEvent(winner);
                        } catch (IOException ioException) {
                            ioException.printStackTrace();
                        }
                        if (result != GAME_OVER) {
                            setClickable(PVEMainBoard.CAN_CLICK);
                        }
                    }
                }
            }
        }
    }
}
